﻿using UnityEngine;

namespace KuiHuaBaoDian.Services.UGUI {

    /// <summary>
    /// 打开UI的选项
    /// </summary>
    public static class UIOpenOptions {

        private static readonly Color BLOCKING_DEFAULT_COLOR = new(0, 0, 0, 0.5f);

        /// <summary>
        /// 实例化
        /// </summary>
        /// <param name="isActive">是否初始处于激活状态</param>
        /// <param name="hasBlocking">是否开启背景遮罩</param>
        /// <param name="isAutoCloseOnClear">是否在清理时自动关闭,清理通常会发生在调用<see cref="IUIService.Goto"/>进行跳转,或主动调用<see cref="IUIService.ClearOpened"/>及<see cref="IUIService.ClearAll"/>时</param>
        /// <param name="isUnique">是否是唯一的</param>
        public static IUIOpenOptions Instantiate(bool isActive = true, bool hasBlocking = false, bool isAutoCloseOnClear = true, bool isUnique = false) {
            var blocking = hasBlocking ? UIBlockingOptions.Instantate(BLOCKING_DEFAULT_COLOR) : null;
            var instance = KHBD.TypeMap.Instantiate<IUIOpenOptions>();
            (instance as IUIOpenOptions.IInitializer).Initialize(isActive, blocking, isAutoCloseOnClear, isUnique);
            return instance;
        }

        /// <summary>
        /// 实例化
        /// </summary>
        /// <param name="isActive">是否初始处于激活状态</param>
        /// <param name="blockingAlpha">背景遮罩透明度,负数值奖沿用上一层的设定值</param>
        /// <param name="isAutoCloseOnClear">是否在清理时自动关闭,清理通常会发生在调用<see cref="IUIService.Goto"/>进行跳转,或主动调用<see cref="IUIService.ClearOpened"/>及<see cref="IUIService.ClearAll"/>时</param>
        /// <param name="isUnique">是否是唯一的</param>
        public static IUIOpenOptions Instantiate(bool isActive = true, float blockingAlpha = 0.5f, bool isAutoCloseOnClear = true, bool isUnique = false) {
            var blocking = UIBlockingOptions.Instantate(new Color(0, 0, 0, blockingAlpha));
            var instance = KHBD.TypeMap.Instantiate<IUIOpenOptions>();
            (instance as IUIOpenOptions.IInitializer).Initialize(isActive, blocking, isAutoCloseOnClear, isUnique);
            return instance;
        }

        /// <summary>
        /// 实例化
        /// </summary>
        /// <param name="isActive">是否初始处于激活状态</param>
        /// <param name="blocking">背景遮罩选项</param>
        /// <param name="isAutoCloseOnClear">是否在清理时自动关闭,清理通常会发生在调用<see cref="IUIService.Goto"/>进行跳转,或主动调用<see cref="IUIService.ClearOpened"/>及<see cref="IUIService.ClearAll"/>时</param>
        /// <param name="isUnique">是否是唯一的</param>
        public static IUIOpenOptions Instantiate(bool isActive = true, IUIBlockingOptions blocking = null, bool isAutoCloseOnClear = true, bool isUnique = false) {
            var instance = KHBD.TypeMap.Instantiate<IUIOpenOptions>();
            (instance as IUIOpenOptions.IInitializer).Initialize(isActive, blocking, isAutoCloseOnClear, isUnique);
            return instance;
        }

        /// <summary>
        /// 快捷实例化一个视图层
        /// </summary>
        /// <returns></returns>
        public static IUIOpenOptions View() => Instantiate(false, false, false, false);

        /// <summary>
        /// 快捷实例化一个浮动层
        /// </summary>
        public static IUIOpenOptions Float() => Instantiate(true, null, false, false);
        public static IUIOpenOptions Float(bool isActive) => Instantiate(isActive, null, false, false);

        /// <summary>
        /// 快捷实例化一个窗口
        /// <para>负数的<paramref name="blockingAlpha"/>会优先使用上层Alpha配置，如果上层Alpha为0，则将应用该值的绝对值作为Alpha。</para>
        /// </summary>
        public static IUIOpenOptions Window(float blockingAlpha = float.NaN, bool isUnique = false) {
            if (float.IsNaN(blockingAlpha)) {
                return Instantiate(true, true, true, isUnique);
            } else {
                return Instantiate(true, blockingAlpha, true, isUnique);
            }
        }

        /// <summary>
        /// 快捷实例化一个窗口的覆盖层
        /// </summary>
        public static IUIOpenOptions WindowOverride() {
            return Instantiate(true, false, true, false);
        }
    }

    /// <summary>
    /// 打开UI的选项
    /// </summary>
    public interface IUIOpenOptions {

        /// <summary>
        /// 初始化写接口
        /// </summary>
        public interface IInitializer {

            /// <summary>
            /// 初始化
            /// </summary>
            /// <param name="isActive">是否初始处于激活状态</param>
            /// <param name="blocking">背景遮罩选项</param>
            /// <param name="isAutoCloseOnClear">是否在清理时自动关闭,清理通常会发生在调用<see cref="IUIService.Goto"/>进行跳转,或主动调用<see cref="IUIService.ClearOpened"/>及<see cref="IUIService.ClearAll"/>时</param>
            /// <param name="isUnique">是否是唯一的</param>
            void Initialize(bool isActive = true, IUIBlockingOptions blocking = null, bool isAutoCloseOnClear = true, bool isUnique = false);
        }

        /// <summary>
        /// 背景遮罩选项
        /// </summary>
        IUIBlockingOptions Blocking { get; }

        /// <summary>
        /// 是否初始处于激活状态
        /// </summary>
        bool IsActive { get; }

        /// <summary>
        /// 是否在清理时自动关闭，
        /// 清理通常会发生在调用<see cref="IUIService.Goto"/>进行跳转,或主动调用<see cref="IUIService.ClearOpened"/>及<see cref="IUIService.ClearAll"/>时
        /// </summary>
        bool IsAutoCloseOnClear { get; }

        /// <summary>
        /// 是否是唯一的
        /// </summary>
        bool IsUnique { get; }
    }

    [Implement(typeof(IUIOpenOptions))]
    internal sealed class KHBD_UIOpenOptions : IUIOpenOptions, IUIOpenOptions.IInitializer {

        public IUIBlockingOptions Blocking { get; private set; }

        public bool IsActive { get; private set; }

        public bool IsAutoCloseOnClear { get; private set; }

        public bool IsUnique { get; private set; }

        void IUIOpenOptions.IInitializer.Initialize(bool isActive, IUIBlockingOptions blocking, bool isAutoCloseOnClear, bool isUnique) {
            Blocking = blocking;
            IsActive = isActive;
            IsAutoCloseOnClear = isAutoCloseOnClear;
            IsUnique = isUnique;
        }
    }
}
